import { FC, useCallback, useEffect, useRef, useState } from "react"
import { FlatList, ImageStyle, ViewStyle } from "react-native"
import { Image } from "expo-image"
import { router, useLocalSearchParams } from "expo-router"

import { AgentInput } from "@/components/AgentInput"
import { MessageItem } from "@/components/NormalMessageItem"
import { Screen } from "@/components/Screen"
import { SSEMessage } from "@/components/SSEMessage"
import { useStores } from "@/models/index"
import { type AgentModel as AgentDescriptor } from "@/services/api/agents"
import type {
  CompletionReq,
  Content as ConversationContent,
  Message as ConversationMessage,
} from "@/services/api/conversations"
import type { ChatMessage } from "@/services/api/types"
import { SSEClient, startConversationCompletion } from "@/services/sse"
import { useAppTheme } from "@/theme/context"
import { $styles } from "@/theme/styles"
import type { ThemedStyle } from "@/theme/types"
import { useHeader } from "@/utils/useHeader"

interface Message extends ChatMessage {
  id: string
  timestamp: Date
  isStreaming?: boolean // 标记是否为流式消息
  images?: string[]
}

interface StreamingMessageRequest {
  id: string
  request: {
    model: string
    messages: ChatMessage[]
    max_tokens: number
    temperature: number
    top_p: number
    presence_penalty: number
  }
}

const ChatPage: FC = function ChatPage() {
  const { agentId, conversationId } = useLocalSearchParams<{
    agentId: string
    conversationId: string
  }>()
  const { agentsStore } = useStores()
  const { themed } = useAppTheme()
  const agent = (agentsStore.modelsByName.get(agentId) as AgentDescriptor | undefined) ?? {
    model: agentId ?? "未知模型",
    iconUrl: "",
    brief: "暂无简介",
    requestModalities: [],
  }

  const [messages, setMessages] = useState<Message[]>([
    {
      id: "1",
      role: "assistant",
      content: agent.brief,
      timestamp: new Date(),
    },
  ])
  const [streamingRequests, setStreamingRequests] = useState<StreamingMessageRequest[]>([])
  const [isLoading, setIsLoading] = useState(false)
  const imageClientsRef = useRef<Record<string, SSEClient | null>>({})

  const flatListRef = useRef<FlatList>(null)
  useEffect(() => {
    return () => {
      Object.values(imageClientsRef.current).forEach((client) => client?.disconnect())
      imageClientsRef.current = {}
    }
  }, [])

  useHeader({
    title: agent.model,
    leftIcon: "back",
    onLeftPress: router.back,
    RightActionComponent: agent.iconUrl ? (
      <Image source={agent.iconUrl} style={themed($agentIcon)} />
    ) : undefined,
  })

  // 使用useCallback优化scrollToBottom函数
  const scrollToBottom = useCallback(() => {
    setTimeout(() => {
      flatListRef.current?.scrollToEnd({ animated: true })
    }, 100)
  }, [])

  // 发送消息的主函数
  const sendMessage = useCallback(
    async (input: string, _attachments: string[] = []) => {
      const content = input.trim()
      if (!content || isLoading) return

      const userMessage: Message = {
        id: Date.now().toString(),
        role: "user",
        content,
        timestamp: new Date(),
      }

      const assistantMessageId = (Date.now() + 1).toString()
      const assistantMessage: Message = {
        id: assistantMessageId,
        role: "assistant",
        content: "",
        timestamp: new Date(),
        isStreaming: true,
      }

      setMessages((prev) => [...prev, userMessage, assistantMessage])
      setIsLoading(true)

      try {
        // 构建请求消息数组
        const requestMessages = [
          {
            role: "system" as const,
            content:
              "You are ChatGPT, a large language agent trained by OpenAI. Answer as concisely as possible.",
          },
          ...messages.map((msg) => ({ role: msg.role, content: msg.content })),
          userMessage,
        ]

        // 创建流式请求
        const streamingRequest: StreamingMessageRequest = {
          id: assistantMessageId,
          request: {
            model: "gpt-3.5-turbo",
            messages: requestMessages,
            max_tokens: 1200,
            temperature: 0.8,
            top_p: 1,
            presence_penalty: 1,
          },
        }

        setStreamingRequests((prev) => [...prev, streamingRequest])
        scrollToBottom()
      } catch (error) {
        console.warn("Chat error:", error)
        setIsLoading(false)
        // Alert.prompt("错误", "发送消息失败，请检查网络连接和API密钥。")
      }
    },
    [isLoading, messages],
  )

  const buildCompletionPayload = useCallback(
    (history: Message[]): CompletionReq => {
      const completionMessages: ConversationMessage[] = history
        .map((msg, index) => {
          const contents: ConversationContent[] = []

          if (msg.content.trim()) {
            contents.push({
              contentType: "text",
              textBlock: { text: msg.content },
            })
          }

          msg.images?.forEach((url) => {
            contents.push({
              contentType: "image",
              imageBlock: { image: { url } },
            })
          })

          if (!contents.length) return null

          return {
            // messageId: msg.id,
            model: agent.model,
            contents,
            direction: msg.role === "user" ? "ask" : "answer",
            ...(conversationId === "new" ? {} : { conversationId }),
          }
        })
        .filter(Boolean) as ConversationMessage[]

      return { messages: completionMessages }
    },
    [agent.model, conversationId],
  )

  const mergeServerMessage = useCallback((serverMessage: ConversationMessage) => {
    const textParts: string[] = []
    const imageUrls: string[] = []

    serverMessage.contents?.forEach((content) => {
      switch (content.contentType) {
        case "text":
          if (content.textBlock?.text) {
            textParts.push(content.textBlock.text)
          }
          break
        case "image":
          if (content.imageBlock?.image?.url) {
            imageUrls.push(content.imageBlock.image.url)
          }
          break
        case "creation":
          content.creationBlock?.creations.forEach((creation) => {
            if (creation.image?.imagePreview?.url) {
              imageUrls.push(creation.image.imagePreview.url)
            }
            if (creation.image?.imageOrigin?.url) {
              imageUrls.push(creation.image.imageOrigin.url)
            }
          })
          break
        default:
          break
      }
    })

    return {
      content: textParts.join("\n").trim(),
      images: imageUrls,
    }
  }, [])

  const handleImageCompletion = useCallback(
    (history: Message[], responseId: string) => {
      const payload = buildCompletionPayload(history)
      console.log("payload", payload)
      imageClientsRef.current[responseId] = startConversationCompletion(payload, {
        onMessage: (event) => {
          const message = event?.data?.message
          if (!message) return
          const { content, images: imageUrls } = mergeServerMessage(message)

          setMessages((prev) =>
            prev.map((msg) =>
              msg.id === responseId
                ? {
                    ...msg,
                    content: content || msg.content,
                    images: imageUrls.length ? imageUrls : msg.images,
                    timestamp: new Date(),
                  }
                : msg,
            ),
          )
          scrollToBottom()
        },
        onComplete: () => {
          setMessages((prev) =>
            prev.map((msg) =>
              msg.id === responseId ? { ...msg, isStreaming: false, timestamp: new Date() } : msg,
            ),
          )
          imageClientsRef.current[responseId]?.disconnect()
          delete imageClientsRef.current[responseId]
          scrollToBottom()
        },
        onError: (error) => {
          console.warn("Image completion error:", error)
          setMessages((prev) =>
            prev.map((msg) =>
              msg.id === responseId
                ? {
                    ...msg,
                    isStreaming: false,
                    content: "图片生成失败，请稍后重试。",
                    timestamp: new Date(),
                  }
                : msg,
            ),
          )
          imageClientsRef.current[responseId]?.disconnect()
          delete imageClientsRef.current[responseId]
        },
      })
    },
    [buildCompletionPayload, mergeServerMessage, scrollToBottom],
  )

  const sendImages = useCallback(
    (uploaded: string[]) => {
      if (!uploaded.length) return

      const timestampBase = Date.now()
      const entries = uploaded.map((url, index) => {
        const userMessage: Message = {
          id: `${timestampBase}-img-${index}`,
          role: "user",
          content: "",
          images: [url],
          timestamp: new Date(),
        }

        const responseMessage: Message = {
          id: `${timestampBase}-img-response-${index}`,
          role: "assistant",
          content: "",
          images: [],
          timestamp: new Date(),
          isStreaming: true,
        }

        return { userMessage, responseMessage }
      })

      const nextMessages = [
        ...messages,
        ...entries.flatMap(({ userMessage, responseMessage }) => [userMessage, responseMessage]),
      ]
      setMessages(nextMessages)
      scrollToBottom()

      entries.forEach(({ userMessage, responseMessage }) => {
        const history = [userMessage]
        handleImageCompletion(history, responseMessage.id)
      })
    },
    [handleImageCompletion, messages, scrollToBottom],
  )

  // 处理流式消息完成
  const handleStreamingComplete = useCallback(
    (messageId: string, completeMessage: string) => {
      console.log("Streaming complete for messageId!:", messageId)
      setMessages((prev) =>
        prev.map((msg) =>
          msg.id === messageId ? { ...msg, content: completeMessage, isStreaming: false } : msg,
        ),
      )
      setStreamingRequests((prev) => prev.filter((req) => req.id !== messageId))
      setIsLoading(false)
      scrollToBottom()
    },
    [scrollToBottom],
  )

  // 处理流式消息错误
  const handleStreamingError = useCallback((messageId: string, error: Error) => {
    console.warn("SSE error:", error)
    setMessages((prev) =>
      prev.map((msg) =>
        msg.id === messageId
          ? { ...msg, content: "抱歉，连接出现问题，请重试。", isStreaming: false }
          : msg,
      ),
    )
    setStreamingRequests((prev) => prev.filter((req) => req.id !== messageId))
    setIsLoading(false)
    // Alert.prompt("错误", "发送消息失败，请检查网络连接和API密钥。")
  }, [])

  // 使用useCallback优化renderMessage函数
  const renderMessage = useCallback(
    ({ item }: { item: Message }) => {
      // 如果是流式消息，使用SSEMessage组件
      if (item.isStreaming) {
        const streamingRequest = streamingRequests.find((req) => req.id === item.id)
        if (streamingRequest) {
          return (
            <SSEMessage
              key={item.id}
              id={item.id}
              request={streamingRequest.request}
              onComplete={(completeMessage) => handleStreamingComplete(item.id, completeMessage)}
              onError={(error) => handleStreamingError(item.id, error)}
            />
          )
        }
      }

      // 普通消息使用MessageItem组件
      return (
        <MessageItem
          key={item.id}
          id={item.id}
          role={item.role}
          content={item.content}
          timestamp={item.timestamp}
        />
      )
    },
    [streamingRequests, handleStreamingComplete, handleStreamingError],
  )

  // 使用useCallback优化keyExtractor
  const keyExtractor = (item: Message) => item.id

  return (
    <Screen preset="fixed" contentContainerStyle={$styles.flex1} keyboardOffset={100}>
      <FlatList
        ref={flatListRef}
        data={messages}
        renderItem={renderMessage}
        keyExtractor={keyExtractor}
        style={themed($messagesList)}
        contentContainerStyle={themed($messagesContainer)}
        onContentSizeChange={scrollToBottom}
      />

      <AgentInput onSend={sendMessage} onImagesChange={sendImages} isLoading={isLoading} />
    </Screen>
  )
}

// Messages styles
const $messagesList: ThemedStyle<ViewStyle> = ({ colors }) => ({
  flex: 1,
  backgroundColor: colors.background,
})

const $messagesContainer: ThemedStyle<ViewStyle> = ({ spacing }) => ({
  paddingHorizontal: spacing.md,
  paddingVertical: spacing.sm,
})

const $agentIcon: ThemedStyle<ImageStyle> = ({ spacing }) => ({
  width: 40,
  height: 40,
  borderRadius: 20,
  marginRight: spacing.md,
})

export default ChatPage
